#include "SingleLinkedList.h"

// 创建一个节点
SingleLinkedListNode *newSingleLinkedListNode(DataType val)
{
    SingleLinkedListNode *node = (SingleLinkedListNode *)malloc(sizeof(SingleLinkedListNode));
    node->val = val;
    node->next = nullptr;
    return node;
}

// 创建一个节点 并指定其next指针
SingleLinkedListNode *newSingleLinkedListNode(DataType val, SingleLinkedListNode *next)
{
    SingleLinkedListNode *node = (SingleLinkedListNode *)malloc(sizeof(SingleLinkedListNode));
    node->val = val;
    node->next = next;
    return node;
}

// 初始化一个单链表
SingleLinkedList *newSingleLinkedList()
{
    SingleLinkedList *list = (SingleLinkedList *)malloc(sizeof(SingleLinkedList));
    list->head = newSingleLinkedListNode(0);
    list->tail = nullptr;
    list->size = 0;
    return list;
}

void subdestroy(SingleLinkedListNode *node)
{
    if (node == nullptr)
    {
        return;
    }
    subdestroy(node->next);
    myInfoLog();
    printf("destroy node %d\n", node->val);
    free(node);
}

// 销毁单链表
void destroy(SingleLinkedList *list)
{
    if (list == nullptr)
    {
        myErrorLog("destroy error: The passed argument list is a null pointer!");
    }
    assertTrue(list != nullptr);
    subdestroy(list->head);
    free(list);
}

// 通过数组 初始化一个单链表
SingleLinkedList *newSingleLinkedList(DataType *arr, int size)
{
    if (arr == nullptr)
    {
        myErrorLog("newSingleLinkedList error: The passed argument arr is a null pointer!");
    }
    assertTrue(arr != nullptr);
    if (size < 0)
    {
        myErrorLog("newSingleLinkedList error: The passed argument size is less than 0!");
    }
    assertTrue(size >= 0);
    SingleLinkedList *list = newSingleLinkedList();
    for (int i = 0; i < size; i++)
    {
        pushBack(list, arr[i]);
    }
    return list;
}

// 打印单链表
void printSingleLinkedList(SingleLinkedList *list)
{
    if (list == nullptr)
    {
        myErrorLog("printSingleLinkedList error: The passed argument list is a null pointer!");
    }
    assertTrue(list != nullptr);
    if (list->head == nullptr)
    {
        myErrorLog("printSingleLinkedList error: The passed argument list->head is a null pointer!");
    }
    assertTrue(list->head != nullptr);
    myInfoLog();
    printf("{SingleLinkedList: %p, size: %d, head: %p, tail: %p, nodes: [", list, list->size, list->head, list->tail);
    SingleLinkedListNode *node = list->head->next;
    while (node != nullptr && node->next != nullptr)
    {
        printf("%d, ", node->val);
        node = node->next;
    }
    if (node != nullptr)
    {
        printf("%d", node->val);
    }
    printf("]}\n");
}

// 通过 DynamicArray 初始化一个单链表
SingleLinkedList *newSingleLinkedList(DynamicArray *arr)
{
    if (arr == nullptr)
    {
        myErrorLog("newSingleLinkedList error: The passed argument arr is a null pointer!");
    }
    assertTrue(arr != nullptr);
    return newSingleLinkedList(arr->datas, arr->size);
}

// 向某一节点后插入一个元素
void insertAfter(SingleLinkedList *list, SingleLinkedListNode *node, DataType val)
{
    if (list == nullptr)
    {
        myErrorLog("insertAfter error: The passed argument list is a null pointer!");
    }
    assertTrue(list != nullptr);
    if (node != list->tail)
    {
        if (node == nullptr)
        {
            myErrorLog("insertAfter error: The passed argument node is a null pointer!");
        }
        assertTrue(node != nullptr);
    }
    if (list->size == 0)
    {
        list->head->next = newSingleLinkedListNode(val);
        list->tail = list->head->next;
    }
    else
    {
        SingleLinkedListNode *newNode = newSingleLinkedListNode(val, node->next);
        node->next = newNode;
        if (node == list->tail)
        {
            list->tail = newNode;
        }
    }
    list->size++;
}

// 向单链表尾部插入一个元素
void pushBack(SingleLinkedList *list, DataType val)
{
    if (list == nullptr)
    {
        myErrorLog("pushBack error: The passed argument list is a null pointer!");
    }
    assertTrue(list != nullptr);
    insertAfter(list, list->tail, val);
}

// 删除某一节点后的节点
void removeAfter(SingleLinkedList *list, SingleLinkedListNode *node)
{
    if (list == nullptr)
    {
        myErrorLog("removeAfter error: The passed argument list is a null pointer!");
    }
    assertTrue(list != nullptr);
    if (node == nullptr)
    {
        myErrorLog("removeAfter error: The passed argument node is a null pointer!");
    }
    assertTrue(node != nullptr);
    SingleLinkedListNode *next = node->next;
    SingleLinkedListNode *newNext = next == nullptr ? nullptr : next->next;
    if (newNext == nullptr)
    {
        list->tail = node;
    }
    myInfoLog();
    printf("destroy node %d\n", node->val);
    free(next);
    node->next = newNext;
    list->size--;
    if (list->size == 0)
    {
        list->tail = nullptr;
    }
}

// 查找某一个元素在单链表中的位置
SingleLinkedListNode *find(SingleLinkedList *list, DataType val)
{
    if (list == nullptr)
    {
        myErrorLog("The passed argument list is a null pointer!");
    }
    assertTrue(list != nullptr);
    SingleLinkedListNode *node = list->head->next;
    while (node != nullptr)
    {
        if (node->val == val)
        {
            return node;
        }
        node = node->next;
    }
    return nullptr;
}

// 更新某一节点的值
void update(SingleLinkedListNode *node, DataType val)
{
    if (node == nullptr)
    {
        myErrorLog("update error: The passed argument node is a null pointer!");
    }
    assertTrue(node != nullptr);
    node->val = val;
}